package com.tanhua.dubbo.api.impl.mongo;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.SoundTime;
import com.tanhua.domain.mongo.UserSound;
import com.tanhua.domain.mongo.UserSoundBlackList;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.SoundTimeVo;
import com.tanhua.domain.vo.SoundVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.SoundApi;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;


import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class SoundApiImpl implements SoundApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserInfoApi userInfoApi;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Override
    public void saveSound(Long userId, String path) {
        UserSound userSound=new UserSound();
        userSound.setUserId(userId);
        userSound.setPath(path);
        Date date = new Date();
        userSound.setCreated(date.getTime());
        userSound.setState(0);
        userSound.setAd(0);

        //当发送语音的时候创建time次数,如果有就不创建
        Query query=new Query(Criteria.where("userId").is(userId));
        SoundTime one = mongoTemplate.findOne(query, SoundTime.class);
        if(one==null){
            SoundTime soundTime=new SoundTime();
            soundTime.setTime(8);
            soundTime.setUserId(userId);
            soundTime.setUpdated(new Date().getTime());
            soundTime.setAd(0);
            soundTime.setPay(0);
            mongoTemplate.save(soundTime);
        }
        //查看soundTime是否存在充值，如果是则发送语音也为ad1
        Integer ad = one.getAd();
        if(ad==1){
            userSound.setAd(1);
        }
        mongoTemplate.save(userSound);
    }


    @Override
    public SoundVo getSound(long userId) {
        //查询本用户是否存在上次未处理的语音，有则释放之前的状态
        /*Query querySoundCache = new Query(Criteria.where("type").is(2));
        UserSoundBlackList one1 = mongoTemplate.findOne(querySoundCache, UserSoundBlackList.class, "user_soundBlackList_" + userId);
        if(one1!=null){
            mongoTemplate.remove(querySoundCache,"user_soundBlackList_" + userId);
        }*/
        redisTemplate.delete("Sound_Linshi_"+userId);
        //查询该用户的黑名单
        Query queryMyBlackList=new Query(Criteria.where("type").is(1));
        List<UserSoundBlackList> userSoundBlackLists = mongoTemplate.find(queryMyBlackList, UserSoundBlackList.class, "user_soundBlackList_" + userId);
        List<ObjectId> id=new ArrayList<>();
        for (UserSoundBlackList userSoundBlackList : userSoundBlackLists) {
            id.add(userSoundBlackList.getSoundId());
        }
        //查询除了自己之外的语音，获取总数并随机
        Query query=new Query(Criteria.where("userId").ne(userId).and("state").is(0).and("id").nin(id));
        Long count = mongoTemplate.count(query, UserSound.class);
        if(count<1){
            return null;
        }
        List<UserSound> userSounds = mongoTemplate.find(query, UserSound.class);
        //判断如果黑名单全是剩下的语音id则返回null

        Random random=new Random();
        while (true) {
            Query querycheck=new Query(Criteria.where("userId").ne(userId).and("state").is(0).and("id").nin(id));
            Long countcheck = mongoTemplate.count(querycheck, UserSound.class);
            if(countcheck<1){
                System.out.println("没有更多的用户了");
                return null;
            }
            int randomNum = random.nextInt(count.intValue());
            //从声音黑名单查询该用户所有黑名单,先判断黑名单该用户是否被不喜欢5条是则不推荐
            UserSound userSound = userSounds.get(randomNum);
            Query queryUserId = new Query(Criteria.where("blackUserId").is(userSound.getUserId()));
            Long count1 = mongoTemplate.count(queryUserId, "user_soundBlackList_" + userId);
            Query querySoundId = new Query(Criteria.where("soundId").is(userSound.getId()));
            UserSoundBlackList one = mongoTemplate.findOne(querySoundId, UserSoundBlackList.class, "user_soundBlackList_" + userId);
            //获取该用户的soundtime
            Query querySountTime=new Query(Criteria.where("userId").is(userSound.getUserId()));
            SoundTime soundtime = mongoTemplate.findOne(querySountTime, SoundTime.class);
            //查出来的随机数用户在黑名单内不为null且小于5，或者已付广告,并且这一条没被不喜欢
            if (( count1<5&&one==null)||soundtime.getAd()==1) {
                //查询可用次数
                Query queryTime=new Query(Criteria.where("userId").is(userId));
                SoundTime time = mongoTemplate.findOne(queryTime, SoundTime.class);
                if(time.getTime()>1) {
                    SoundVo soundVo = new SoundVo();
                    UserInfo byId = userInfoApi.findById(userSound.getUserId());
                    BeanUtils.copyProperties(byId,soundVo);
                    soundVo.setId(byId.getId().intValue());
                    soundVo.setSoundUrl(userSound.getPath());
                    Integer time1 = time.getTime();
                    time1=time1-1;
                    soundVo.setRemainingTimes(time1);
                    //更新次数
                    Update update=new Update();
                    update.set("time",time1);
                    mongoTemplate.updateFirst(queryTime,update,SoundTime.class);
                    //更新语音状态
                    Update update1=new Update();
                    update1.set("state",1);
                    Query queryUpdateState=new Query(Criteria.where("id").is(userSound.getId()));
                    mongoTemplate.updateFirst(queryUpdateState,update1,UserSound.class);
                    //语音放到临时拉黑表状态为2
                    redisTemplate.opsForValue().set("Sound_Linshi_"+userId,userSound.getId().toString());
                   /* UserSoundBlackList blackList=new UserSoundBlackList();
                    blackList.setSoundId(userSound.getId());
                    blackList.setType(2);
                    blackList.setCreated(new Date().getTime());
                    blackList.setBlackUserId(byId.getId());
                    blackList.setSoundPath(userSound.getPath());
                    mongoTemplate.save(blackList,"user_soundBlackList_"+userId);*/
                    //将语音放到同一个拉黑表,方便没机会的时候和重复听取未处理的语音
                    UserSoundBlackList blackList1=new UserSoundBlackList();
                    blackList1.setSoundId(userSound.getId());
                    blackList1.setCreated(new Date().getTime());
                    blackList1.setBlackUserId(byId.getId());
                    blackList1.setSoundPath(userSound.getPath());
                    blackList1.setType(3);
                    mongoTemplate.save(blackList1,"user_soundBlackList_"+userId);
                    return soundVo;
                }else {
                    System.out.println("获取的是未执行的");
                    //查询状态为3的的黑名单信息
                    Query queryRepeat =new Query(Criteria.where("type").is(3));
                    List<UserSoundBlackList> userSoundBlackLists1 = mongoTemplate.find(queryRepeat, UserSoundBlackList.class, "user_soundBlackList_" + userId);
                    if(userSoundBlackLists1.size()>0) {
                        Random random1 = new Random();
                        int i = random1.nextInt(userSoundBlackLists1.size());
                        UserSoundBlackList blackList = userSoundBlackLists1.get(i);
                        SoundVo soundVo=new SoundVo();
                        UserInfo byId = userInfoApi.findById(blackList.getBlackUserId());
                        BeanUtils.copyProperties(byId,soundVo);
                        soundVo.setId(byId.getId().intValue());
                        soundVo.setSoundUrl(userSound.getPath());
                        soundVo.setRemainingTimes(1);
                        //将未处理的存到redis方便以后喜欢和不喜欢获取
                        redisTemplate.opsForValue().setIfAbsent("user_soundRepeat_"+userId,blackList.getSoundId().toString(),1, TimeUnit.HOURS);
                        return soundVo;
                    }else {
                        return null;
                    }
                }
            }else {
                Query query1=new Query(Criteria.where("userId").is(soundtime.getUserId()));
                List<UserSound> userSounds1 = mongoTemplate.find(query1, UserSound.class);
                for (UserSound sound : userSounds1) {
                    id.add(sound.getId());
                }
            }
        }
    }
    //定时任务更改次数
    @Override
    public void updateSoundTime() {

        //更新非充值用户
        Update update=new Update();
        update.set("time",11);
        Query query = new Query(Criteria.where("ad").is(0));
        mongoTemplate.updateFirst(query,update,SoundTime.class);
        //更新充值用户
        Query query1=new Query(Criteria.where("ad").is(1));
        Update update1=new Update();
        update1.inc("time",11);
        mongoTemplate.updateMulti(query1,update1,SoundTime.class);
    }

    @Override
    public PageResult getSoundTimeList(int page, int pagesize, String id) {
        if(!id.equals("")&&id!=null) {
            Query query = new Query(Criteria.where("userId").is(Integer.parseInt(id))).skip((page-1)*pagesize).limit(pagesize);
            long count = mongoTemplate.count(query,SoundTime.class);
            List<SoundTime> soundTimes = mongoTemplate.find(query, SoundTime.class);
            List<SoundTimeVo> list=new ArrayList<>();
            for (SoundTime soundTime : soundTimes) {
                SoundTimeVo soundTimeVo=new SoundTimeVo();
                Integer ad = soundTime.getAd();
                String updated = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(soundTime.getUpdated());
                UserInfo byId = userInfoApi.findById(Long.parseLong(id));
                Query query1=new Query(Criteria.where("userId").is(Integer.parseInt(id)));
                soundTimeVo.setTime(soundTime.getTime());
                soundTimeVo.setId(soundTime.getUserId().toString());
                soundTimeVo.setCount(new Long(mongoTemplate.count(query1,UserSound.class)).intValue());
                soundTimeVo.setIsdefault(ad);
                soundTimeVo.setName(byId.getNickname());
                soundTimeVo.setUpdated(updated);
                list.add(soundTimeVo);
            }
            PageResult pageResult=new PageResult(page,pagesize,new Long(count).intValue(),list);
            return pageResult;
        }else {
            Query query = new Query().skip((page-1)*pagesize).limit(pagesize);
            long count = mongoTemplate.count(query,SoundTime.class);
            List<SoundTimeVo> list=new ArrayList<>();
            List<SoundTime> soundTimes = mongoTemplate.find(query, SoundTime.class);
            for (SoundTime soundTime : soundTimes) {
                SoundTimeVo soundTimeVo=new SoundTimeVo();
                Integer ad = soundTime.getAd();
                String updated = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(soundTime.getUpdated());
                UserInfo byId = userInfoApi.findById(soundTime.getUserId());
                Query query1=new Query(Criteria.where("userId").is(soundTime.getUserId()));
                soundTimeVo.setId(soundTime.getUserId().toString());
                soundTimeVo.setTime(soundTime.getTime());
                soundTimeVo.setCount(new Long(mongoTemplate.count(query1,UserSound.class)).intValue());
                soundTimeVo.setIsdefault(ad);
                soundTimeVo.setName(byId.getNickname());
                soundTimeVo.setUpdated(updated);
                list.add(soundTimeVo);
            }
            PageResult pageResult=new PageResult(page,pagesize,new Long(count).intValue(),list);
            return pageResult;
        }
    }

    @Override
    public void updateSoundTimeAd(String id) {
        System.out.println("更新语音次数");
        Query query=new Query(Criteria.where("userId").is(Integer.parseInt(id)));
        SoundTime one = mongoTemplate.findOne(query, SoundTime.class);
        Integer ad = one.getAd();
        Update update=new Update();
        if(ad==1){
            update.set("ad",0);
            update.set("updated",new Date().getTime());
            mongoTemplate.updateFirst(query,update,SoundTime.class);
        }else {
            update.set("ad",1);
            update.set("updated",new Date().getTime());
            mongoTemplate.updateFirst(query,update,SoundTime.class);
        }
    }

    @Override
    public void updateSoundTimeTime(String id,String time) {

        Query query=new Query(Criteria.where("userId").is(Integer.parseInt(id)));
        Update update=new Update();
        update.set("time",Integer.parseInt(time));
        update.set("updated",new Date().getTime());
        mongoTemplate.updateFirst(query,update,SoundTime.class);
    }

    @Override
    public void updateSoundTimeAdOntime(String userId, int ad) {
        Query query=new Query(Criteria.where("userId").is(Integer.parseInt(userId)));
        Update update=new Update();
        update.set("ad",ad);
        mongoTemplate.updateFirst(query,update,SoundTime.class);
    }
}
